package ar.uba.is2.tr.sensor;

import java.util.Date;
import java.util.Random;

import org.apache.log4j.Logger;
import org.hibernate.Transaction;
import org.hibernate.classic.Session;

import ar.uba.is2.common.mensaje.DatoSensado;
import ar.uba.is2.common.threads.ThreadManager;
import ar.uba.is2.common.utils.HibernateUtil;

// esta clase modela el sensor que se conecta a la TR. El sennsor consta de
// id: el id del sensor (podria se el numero de serie)
// message: mensaje a enviar (el ultimo sensado)
// frecuencia: la frecuencia de sensado

public class SensorMock implements Sensor {

	private static final Logger logger = Logger.getLogger(Sensor.class);

	private int id;
	private long frecuencia;
	private Random sensor;

	public SensorMock(int id, long frecuenciaSensado) {
		this.id=id;
		this.frecuencia = frecuenciaSensado;
		sensor = new Random(new Date().getTime() + id * frecuencia);
		ThreadManager.instance.crearYCorrerThread(new SensorDaemon());
	}
	
	public void setFrecuencia(long frecuencia) {
		this.frecuencia = frecuencia;
	}

	private void publicarDatoSensado(DatoSensado datoSensado) {
		logger.info(String.format("El sensor %s obtuvo el valor %s en %s", datoSensado.getIdSensor(), datoSensado.getValor(), datoSensado.getFechaSensada()));
		this.saveDatoSensado(datoSensado);
	}

	private void saveDatoSensado(DatoSensado datoSensado) {
		Session session = HibernateUtil.getSession();
		Transaction tx = session.beginTransaction();
        
        session.save(datoSensado);
		tx.commit();
		session.flush();
		session.close();
	}

	private float sensar() {
		return sensor.nextFloat() * 100;
	}
	
	private class SensorDaemon implements Runnable {

		public void run() {
			try {
				while (true) {
					float valorSensado = sensar();

					DatoSensado dato = new DatoSensado(valorSensado, SensorMock.this.id, new Date());
					
					publicarDatoSensado(dato);

					synchronized (this) {
						wait(SensorMock.this.frecuencia);
					}
				}
			} catch (InterruptedException e) {
			}
		}

	}
}
